import M from '../../../../common/typeMutations'
import A from '../../../../common/typeActions'
import S from '../../../../common/localStore'
import ipcs from '../../../../common/typeIpcs'
import events from '../../../../common/typeEvents'
import fs from 'fs'
import uuid from 'uuid/v4'
import editorServer from '../../../../server/slideEditor/editorServer'
import SQLite from '../../../../common/SQLiteHelper'
import path from 'path'
import vue from 'vue'
import evidenceCatalog from '../../../../config/evidenceCatalogTree'
import appearCourt from './appearCourt'

let defaultElement = {
  id: '',
  name: '', // 名称
  text: '', // 文本内容
  html: '', // HTML片段
  type: '', // 元素类型
  path: '', // 文件路径
  left: 0, // 距离容器左边比例
  top: 0, // 距离容器上边比例
  width: 0, // 元素宽度比例
  height: 0, // 元素高度比例
  lockWidth: false, // 锁定宽度
  lockHeight: false, // 锁定高度
  lockMove: false,
  lockSelect: false,
  index: 1, // 元素索引
  show: true, // 是否显示
  isEdit: false,
  templateElement: false,
  fileCode: '',
  style: {// 元素样式
    'font-family': 'SimHei',
    'font-size': '28px',
    'font-weight': '',
    'font-style': '',
    'text-decoration': '',
    'text-align': 'left',
    'color': '#000000'
  },
  animation: []
}

const state = {
  isShowElement: false,
  isEditState: false,
  isEditSlide: false,
  slide: null, // 幻灯片参数对象
  slides: [], // 幻灯片播放队列
  fallbackStates: [], // 回退状态
  currentStateIndex: -1, // 当前状态索引
  elements: [],
  files: [],
  styles: [], // 幻灯片风格
  templates: null, // 幻灯片版式
  covers: [], // 幻灯片封面
  fontStyles: [],
  animations: [],
  activeElement: null, // 当前活动元素
  defaultElement: null, // 默认元素属性
  copyElement: null, // 复制节点
  cursorState: 'normal', // 鼠标状态
  isPlay: false, // 是否放映
  autoPlay: null, // play:播放；pause:暂停
  preview: false, // 预览
  isCropImage: false, // 是否裁剪图片
  isShowCover: false, // 是否显示封面
  isZoomEditor: false, // 是否缩放编辑区
  expandScreen: false, // 是否
  defaultFiles: [],
  zoomImage: {isZoom: false, isDraw: false, image: null, width: 0, height: 0, rotate: 0, left: 0, top: 0, sign: []},
  maskCanvas: {trajectorys: [], zoomImage: {}, isDraw: false, isZoom: false, drawMode: 'FreeLine'},
  temporaryFile: {
    files: [],
    trajectorys: [],
    texts: [],
    zoomImage: {},
    scroll: 0,
    isDraw: false,
    isZoom: false,
    drawMode: 'FreeLine'
  }, // 临时文件
  DefaultCover: '',
  DefaultBackground: 'f8dd08bd-22fd-7a19-0206-041893e0e340',
  DefaultTemplate: [],
  customized: {
    PlaySpeed: 2, // 播放速度
    ContainerScale: 'fullScreen', // 容器比例；rectangle,square,
    PlayNextSlide: true, // 播放下一节点
    AutoPreview: true, // 预览时是否自动播放
    DefaultZoomMultiples: 100,
    DefaultElementStyle: {name: 'Microsoft YaHei', size: '28px', color: '#FFFFFF', fontWeight: 'blod'}, // 元素
    DefaultGraphStyle: {width: '2px', color: '#FF0000'}, // 标注
    DefaultAnimation: {
      id: '94f71c0c-041c-678c-147a-38af313460ce',
      name: 'fadeinB',
      time: '2s',
      order: 1,
      isPlay: true
    }, // 动画
    DefaultBrush: {width: 4, color: '#FF0000'},
    AutoAddCatalog: false
  }
}

let timer = null
const mutations = {
  /**
   * 公用属性
   */
  // 设置状态
  [M.SLIDEEDITOR.SetState] (state, obj) {
    try {
      for (let attrName in obj) {
        if (state[attrName] === undefined) {
          this._vm.$set(state, attrName, obj[attrName])
        } else {
          state[attrName] = obj[attrName]
        }
      }
    } catch (error) {
      throw error
    }
  },
  // 设置状态属性
  [M.SLIDEEDITOR.SetStateAttr] (state, arr) {
    try {
      for (let i = 0; i < arr.length; i++) {
        if (state[arr[i].attrName] === undefined) {
          this._vm.$set(state, arr[i].attrName, arr[i].attrValue)
        } else {
          state[arr[i].attrName] = arr[i].attrValue
        }
      }
    } catch (error) {
      throw error
    }
  },

  // 设置鼠标状态
  [M.SLIDEEDITOR.SetCursorState] (state, value) {
    try {
      state.cursorState = value || 'normal'
    } catch (error) {
      throw error
    }
  },
  // 设置预览状态
  [M.SLIDEEDITOR.SetPreviewState] (state, value) {
    try {
      state.preview = value
      if (!state.preview && timer) clearTimeout(timer)
      if (state.activeElement) state.activeElement = null

      state.elements.forEach(function (item) {
        item.isEdit = false
        if (item.animation && item.animation.length > 0) {
          item.show = !state.preview
          item.animation.forEach((am) => {
            am.isPlay = !state.preview
          })
        } else {
          item.show = true
        }
      })
      if (state.preview && state.customized.AutoPreview) {
        this.commit(M.SLIDEEDITOR.NextAnimation)
      }
    } catch (error) {
      throw error
    }
  },
  // 设置播放状态
  [M.SLIDEEDITOR.SetPlayState] (state, value) {
    try {
      let self = this
      if (state.activeElement) {
        state.activeElement = null
      }
      if (state.isPlay !== value) this._vm.$eventBus.$emit(events.SlideEditor.SlideStateChanged, value)
      state.isPlay = value
      // 隐藏存在动画的元素
      state.elements.forEach(function (item) {
        item.isEdit = false
        if (item.animation && item.animation.length > 0) {
          item.show = state.isShowElement || !state.isPlay
          item.animation.forEach((am) => {
            am.isPlay = state.isShowElement || !state.isPlay
          })
        } else {
          item.show = true
        }
      })

      if (state.isPlay) {
        state.preview = false
        self._vm.$nextTick(function () {
          if (state.autoPlay === 'play') {
            if (timer) clearTimeout(timer)
            timer = setTimeout(() => {
              self.commit(M.SLIDEEDITOR.NextAnimation)
            }, state.customized.PlaySpeed * 1000)
          }
          self._vm.$electron.ipcRenderer.send(ipcs.MAIN.openExpandScreen, {
            id: 'SlideExpandScreen',
            URL: 'SlideEditor',
            State: state
          })
        })
      } else {
        // 结束放映，终止播放
        state.autoPlay = null
        if (timer) clearTimeout(timer)
        this.dispatch(A.SLIDEEDITOR.ClearEditorMask)
        this._vm.$electron.ipcRenderer.send(ipcs.MAIN.closeExpandScreen)
      }
      state.isShowElement = false
    } catch (error) {
      throw error
    }
  },
  // 设置自动播放
  [M.SLIDEEDITOR.SetAutoPlay] (state, value) {
    try {
      let isPlayNextAni = false
      if (state.isPlay) {
        isPlayNextAni = value !== 'pause'
      } else {
        isPlayNextAni = !!(state.autoPlay === 'pause' && value === 'play')
      }
      state.autoPlay = value
      if (!state.isPlay) this.commit(M.SLIDEEDITOR.SetPlayState, true)
      if (isPlayNextAni) {
        this.commit(M.SLIDEEDITOR.NextAnimation)
      } else if (state.autoPlay === 'pause' && timer) clearTimeout(timer)
    } catch (error) {
      throw error
    }
  },
  /**
   * 幻灯片对象
   */
  // 初始化幻灯片
  [M.SLIDEEDITOR.InitSlide] (state, obj) {

  },
  // 设置幻灯片标题
  [M.SLIDEEDITOR.SetSlideTitle] (state, text) {
    let el = state.elements.find(x => x.type === 'TEXT' && x.index === 1)
    if (el) el.text = el.html = text
  },
  // 设置幻灯片参数
  async [M.SLIDEEDITOR.SetSlideProps] (state, obj) {
    try {
      state.slide = obj
      state.isCropImage = false
      if (state.slide) {
        state.expandScreen = state.slide.expandScreen
        if (state.slide.expandScreen) state.customized.ContainerScale = 'fullScreen'
        await this.dispatch(A.SLIDEEDITOR.InitSlideElement)
      } else {
        this.commit(M.SLIDEEDITOR.SetSlideElement, {els: [], files: []})
      }
    } catch (error) {
      throw error
    }
  },
  // 设置幻灯片元素
  [M.SLIDEEDITOR.SetSlideElement] (state, obj) {
    try {
      state.activeElement = null
      // state.elements = obj
      state.elements = obj && obj.els ? obj.els : []
      state.files = obj && obj.files ? obj.files : []
      if (state.isPlay) {
        this.commit(M.SLIDEEDITOR.SetPlayState, true)
      }
      this.dispatch(A.SLIDEEDITOR.ClearEditorMask)
      this.dispatch(A.SLIDEEDITOR.SetCoverShowState, false)
    } catch (error) {
      throw error
    }
  },
  // 设置幻灯片属性
  [M.SLIDEEDITOR.SetSlideAttr] (state, obj) {
    try {
      if (!Array.isArray(obj)) {
        obj = [obj]
      }
      for (let i = 0; i < obj.length; i++) {
        if (state[obj[i].attrName] === undefined) {
          this._vm.$set(state, obj[i].attrName, obj[i].attrValue)
        } else {
          state[obj[i].attrName] = obj[i].attrValue
        }
      }
    } catch (error) {
      throw error
    }
  },
  // 设置幻灯片风格
  [M.SLIDEEDITOR.SetSlideStyle] (state, value) {
    try {
      if (!state.slide) return
      let obj = state.DefaultTemplate.find((x) => {
        return x.sid === value
      })
      if (!obj) return
      state.slide.sid = obj.sid
      this.dispatch(A.SLIDEEDITOR.SetSlideTempalte, obj.id)
    } catch (error) {
      throw error
    }
  },
  // 设置幻灯片版式
  [M.SLIDEEDITOR.SetSlideTempalte] (state, value) {
    try {
      if (!state.slide) return
      state.slide.tid = value
      this.dispatch(A.SLIDEEDITOR.ChangeSlideTemplate, value)
      this._vm.$eventBus.$emit(events.SlideEditor.SlideStyleAndTemplateChanged, {
        id: state.slide.id,
        sid: state.slide.sid,
        tid: state.slide.tid
      })
    } catch (error) {
      throw error
    }
  },
  // -----------------------------------------------------------------
  /**
   * 封面
   */

  // 添加封面
  [M.SLIDEEDITOR.AddCover] (state, filePath) {
    try {
      let id = uuid()
      let {name, ext} = path.parse(filePath)
      let base64 = `data:image/${ext.replace('.', '')};base64,` + fs.readFileSync(filePath).toString('base64')
      state.covers.push({id, coverName: name, coverText: '', coverImage: base64, isCustom: true})
      this.dispatch(A.SLIDEEDITOR.SetSelectedCover, id)
    } catch (error) {
      throw error
    }
  },
  // 设置封面文本
  [M.SLIDEEDITOR.SetCoverText] (state, text) {
    try {
      this.getters.defaultCover.coverText = text
    } catch (error) {
      throw error
    }
  },
  // 设置选中封面
  [M.SLIDEEDITOR.SetSelectedCover] (state, id) {
    try {
      state.DefaultCover = id
      // let style = state.styles.find(x => { return x.sffm == 'True' })
      // if (style) style.image = this.getters.defaultCover.coverImage
    } catch (error) {
      throw error
    }
  },
  // 设置封面显示状态
  [M.SLIDEEDITOR.SetCoverShowState] (state, value) {
    try {
      state.isShowCover = value
      let temporaryFile = {files: [], texts: [], isCover: true, drawMode: 'FreeLine'}
      if (state.isShowCover) {
        let defaultCover = this.getters.defaultCover
        temporaryFile.files = [{id: uuid(), url: defaultCover.coverImage}]
        temporaryFile.texts = [
          {
            text: defaultCover.coverText,
            width: 0.5,
            height: 0.8,
            textAlign: 'center'
          }]
      }
      this.dispatch(A.SLIDEEDITOR.SetTemporaryFile, temporaryFile)
    } catch (error) {
      throw error
    }
  },
  // --------------------------------------------------------------------------------------------
  /**
   * 编辑器背景
   */
  // 添加编辑器背景
  [M.SLIDEEDITOR.AddBackgroundImage] (state, arr) {
  },
  // 设置默认背景
  [M.SLIDEEDITOR.SetSelectedBackground] (state, id) {
    try {
      state.DefaultBackground = id
    } catch (error) {
      throw error
    }
  },
  // --------------------------------------------------------------------------------------------
  /**
   * 编辑器版式
   */
  // 设置默认版式
  [M.SLIDEEDITOR.SetSelectedTemplate] (state, obj) {
    try {
      let template = state.DefaultTemplate.find((x) => {
        return x.sid === obj.sid
      })
      if (template) {
        template.id = obj.id
      } else {
        state.DefaultTemplate.push(obj)
      }
    } catch (error) {
      throw error
    }
  },
  // --------------------------------------------------------------------------------------------
  /**
   * 元素对象
   */
  // 添加幻灯片元素
  [M.SLIDEEDITOR.AddSlideElements] (state, arr) {
    try {
      if (!Array.isArray(arr) && typeof arr === 'object') arr = [arr]
      if (!arr || !Array.isArray(arr)) return
      let maxIndex = 0
      state.elements.forEach((item) => {
        maxIndex = item.index > maxIndex ? item.index : maxIndex
      })
      arr.forEach((item) => {
        let defaultEl = getDefaultElement({}, state.customized)
        let addEl = getElementLocSize(state.elements, item, defaultEl)
        if (addEl) {
          maxIndex++
          addEl.index = maxIndex
          // 设置元素类型
          addEl.type = item.type
          // 设置元素名称
          addEl.name = addEl.type + addEl.index
          state.elements.push(addEl)
        }
      })
    } catch (error) {
      throw error
    }
  },
  // 添加活动元素
  [M.SLIDEEDITOR.AddActiveElement] (state, obj) {
    try {
      let defaultElement = {...state.defaultElement}
      defaultElement.left = obj.X
      defaultElement.top = obj.Y
      state.elements.push(defaultElement)
      state.activeElement = defaultElement
    } catch (error) {
      throw error
    }

    // state.cursorState = "setLowerRightCorner";
  },
  // 设置添加默认元素
  [M.SLIDEEDITOR.SetDefaultElement] (state, obj) {
    try {
      let defualtEl = getDefaultElement(obj, state.customized)
      // 获取元素集合中最大索引
      state.elements.forEach(function (item) {
        defualtEl.index = defualtEl.index <= item.index ? (item.index + 1) : defualtEl.index
      })

      defualtEl.name = defualtEl.type + defualtEl.index
      state.cursorState = 'addElement'
      state.defaultElement = defualtEl
    } catch (error) {
      throw error
    }
  },
  // 设置活动元素
  [M.SLIDEEDITOR.SetActiveElement] (state, obj) {
    try {
      if (state.activeElement) state.activeElement.isEdit = false
      state.activeElement = obj
    } catch (error) {
      throw error
    }
  },
  // 复制元素
  [M.SLIDEEDITOR.CopyElement] (state) {
    try {
      let file = state.files.find((item) => {
        return item.ID === state.activeElement.path
      })
      state.copyElement = {element: JSON.parse(JSON.stringify(state.activeElement)), file}
      console.log('元素已复制')
    } catch (error) {
      throw error
    }
  },
  // 粘贴元素
  [M.SLIDEEDITOR.PasteElement] (state) {
    try {
      let el = state.copyElement.element
      let file = state.copyElement.file

      if (file && !state.files.find((x) => {
        return x.ID === file.ID
      })) {
        state.files.push(file)
      }

      // 设置元素位置
      if (el.left + el.width + 0.1 > 1) {
        el.left = 1 - el.width
      } else {
        el.left += 0.1
      }
      if (el.top + el.height + 0.1 > 1) {
        el.top = 1 - el.height
      } else {
        el.top += 0.1
      }

      let els = this.getters.elements
      let copyEl = JSON.parse(JSON.stringify(el))
      if (els.length) {
        copyEl.index = els[els.length - 1].index + 1
      } else {
        copyEl.index = 1
      }
      copyEl.id = uuid()
      copyEl.name = copyEl.type + copyEl.index
      state.elements.push(copyEl)
      this.commit(M.SLIDEEDITOR.SetActiveElement, state.elements[state.elements.length - 1])
      console.log('元素已粘贴')
    } catch (error) {
      throw error
    }
  },
  // 删除活动元素
  [M.SLIDEEDITOR.DelActiveElement] (state, arr) {
    try {
      state.activeElement = null
      arr.forEach((item) => {
        let elIndex = state.elements.findIndex((x) => {
          return x.id === item
        })
        state.elements.splice(elIndex, 1)
      })
      console.log('元素已删除')
    } catch (error) {
      throw error
    }
  },
  // 设置元素属性
  [M.SLIDEEDITOR.SetElementAttr] (state, obj) {
    try {
      if (!Array.isArray(obj)) obj = [obj]
      obj.forEach((item) => {
        let el = state.elements.find((x) => {
          return x.id === item.id
        })
        if (el) el[item.attrName] = item.attrValue
      })
    } catch (error) {
      throw error
    }
  },
  // 添加外部文档
  [M.SLIDEEDITOR.AddDocument] (state, obj) {
    try {
      let maxIndex = 0
      let spliceIndex
      let docEl = null
      // 获取最大索引
      state.elements.forEach((item, index) => {
        maxIndex = item.index > maxIndex ? item.index : maxIndex
        if (item.id === obj.id) {
          docEl = item
          spliceIndex = index
        }
      })

      if (!docEl || !obj.image) return
      // 删除文档项
      state.elements.splice(spliceIndex, 1)

      if (process.browser) {
        obj.image.Files.forEach((item) => {
          let imgEl = JSON.parse(JSON.stringify(docEl))
          imgEl.id = uuid()
          imgEl.type = 'IMAGE'
          imgEl.index = ++maxIndex
          imgEl.name = `IMAGE${imgEl.index}`
          imgEl.fileCode = item.WJID
          imgEl.path = item.ID
          state.elements.push(imgEl)
        })

        this.dispatch(A.SLIDEEDITOR.AddDossierFile, obj.image.Files)
      } else {
        obj.image.forEach((item) => {
          let imgEl = JSON.parse(JSON.stringify(docEl))
          imgEl.id = uuid()
          imgEl.type = 'IMAGE'
          imgEl.index = ++maxIndex
          imgEl.name = `IMAGE${imgEl.index}`
          imgEl.fileCode = item.fileID
          imgEl.path = item.imageID
          state.elements.push(imgEl)
        })
      }
    } catch (error) {
      throw error
    }
  },
  // 设置元素编辑状态
  [M.SLIDEEDITOR.SetElementEidtState] (state, obj) {
    try {
      let el = state.elements.find((x) => {
        return x.id === obj.id
      })
      if (el) el.isEdit = obj.isEdit
    } catch (error) {
      throw error
    }
  },
  // 设置文本元素图片
  [M.SLIDEEDITOR.SetTextElementImage] (state, obj) {
    try {
      let el = state.elements.find((x) => {
        return x.id === obj.id
      })
      if (el) this._vm.$set(el, 'img', obj.img)
    } catch (error) {
      throw error
    }
  },
  // --------------------------------------------------------------------------------------------
  /**
   * 元素动画
   */
  // 添加元素进入动画
  [M.SLIDEEDITOR.AddElementAnimation] (state, animation) {
    try {
      if (!state.activeElement) return

      if (state.activeElement.animation === undefined) {
        this._vm.$set(state.activeElement, 'animation', [])
      }
      if (!animation) {
        state.activeElement.animation = []
        return
      }

      let defaultAni = {...state.customized.DefaultAnimation}
      defaultAni.id = animation.id
      defaultAni.name = animation.name
      if (animation.time) defaultAni.time = animation.time

      if (defaultAni.id && defaultAni.name && defaultAni.time) {
        state.activeElement.animation = [defaultAni]
      } else {
        state.activeElement.animation = []
      }
    } catch (error) {
      throw error
    }
  },
  // 删除元素进入动画
  [M.SLIDEEDITOR.DelElementAnimation] (state, obj) {

  },
  // 上一动画
  [M.SLIDEEDITOR.PreviousAnimation] (state) {
    try {
      state.isShowElement = true
      let elements = this.getters.elements
      if (!elements || !elements.length) return
      // 获取容器显示并且存在动画元素
      let loadElement = elements.filter(function (x) {
        return x.show === true && x.animation && x.animation.length
      }).sort(function (x, y) {
        return y.index - x.index
      })
      // 当容器中存在具有动画的元素对象时隐藏最后加载元素
      if (loadElement.length > 0) {
        loadElement[0].animation.forEach((item) => {
          item.isPlay = false
        })
        loadElement[0].show = false
      } else {
        // 当元素具有动画的对象元素全部隐藏完成后加载上一幻灯片对象
        // 检查是否播放上一节点内容
        if (state.preview || !state.customized.PlayNextSlide) return
        let index = state.slides.findIndex((item) => {
          return item.data.id === state.slide.id
        }) - 1
        if (index < 0) return

        this.dispatch(A.SLIDEEDITOR.InitSlide, state.slides[index])
      }
    } catch (error) {
      throw error
    }
  },
  // 下一动画
  [M.SLIDEEDITOR.NextAnimation] (state, isFristExec) {
    try {
      state.isShowElement = false
      let elements = this.getters.elements
      if (!elements || !elements.length) return
      let waitTime = state.customized.PlaySpeed// 自动播放等待时间
      // 获取容器中动画未播放完的元素对象
      let lastEle = elements.filter(function (x) {
        return x.show === true && x.animation && x.animation.filter((ani) => {
          return !ani.isPlay
        }).length > 0
      })
      // 当存在动画未播放完成的元素对象时继续播放动画
      if (lastEle.length > 0) {
        // 获取播放动画
        let animation = lastEle[0].animation.filter((x) => {
          return !x.isPlay
        }).sort((x, y) => {
          return x.order > y.order
        })[0]
        animation.isPlay = true
        waitTime = parseInt(animation.time)
      } else {
        // 动画已播放完成时加载下一元素对象
        let unLoadEle = elements.filter(function (x) {
          return x.show === false
        }).sort((x, y) => {
          return x.index - y.index
        })
        // 当存在未加载元素对象时继续加载下一元素
        if (unLoadEle.length > 0) {
          unLoadEle[0].show = true
          let animation = unLoadEle[0].animation.sort((x, y) => {
            return x.order > y.order
          })[0]
          animation.isPlay = true
          waitTime = parseInt(animation.time)
        } else {
          // 当元素以全部加载完成时加载下一幻灯片对象
          if (state.preview || !state.customized.PlayNextSlide) return
          let index = state.slides.findIndex((item) => {
            return item.data.id === state.slide.id
          }) + 1
          if (index >= state.slides.length) return

          this.dispatch(A.SLIDEEDITOR.InitSlide, state.slides[index])
        }
      }
      if (isFristExec !== true) {
        this.dispatch(A.SLIDEEDITOR.SetCoverShowState, false)
      }
      if (!elements.filter(function (x) {
        return x.show === false
      }).length) {
        waitTime += state.customized.PlaySpeed
      }

      let commit = this.commit
      let autoPlay = state.preview ? state.customized.AutoPreview : (state.autoPlay === 'play')
      if (autoPlay && waitTime > 0) {
        // 清除计时器
        if (timer) clearTimeout(timer)
        timer = setTimeout(() => {
          if (autoPlay) commit(M.SLIDEEDITOR.NextAnimation)
        }, waitTime * 1000)
      }
    } catch (error) {
      throw error
    }
  },
  // --------------------------------------------------------------------------------------------
  /**
   * 元素内容
   */
  // 设置活动元素属性
  [M.SLIDEEDITOR.SetActiveElementAttr] (state, obj) {
    try {
      if (!state.activeElement) return
      if (state.activeElement[obj.attrName] === undefined) {
        this._vm.$set(state.activeElement, obj.attrName, obj.attrValue)
      } else {
        state.activeElement[obj.attrName] = obj.attrValue
      }
    } catch (error) {
      throw error
    }
  },
  // 设置活动元素字体样式
  [M.SLIDEEDITOR.SetActiveElementFont] (state, obj) {
    try {
      if (!state.activeElement || !state.activeElement.style) return
      if (!Array.isArray(obj)) obj = [obj]
      for (let i = 0; i < obj.length; i++) {
        if (state.activeElement.style[obj[i].attrName] === undefined) {
          this._vm.$set(state.activeElement.style, obj[i].attrName, obj[i].attrValue)
        } else {
          state.activeElement.style[obj[i].attrName] = obj[i].attrValue
        }
      }
    } catch (error) {
      throw error
    }
  },
  // 设置活动元素位置和大小
  [M.SLIDEEDITOR.SetActiveEleLocAndSize] (state, obj) {
    try {
      if (!state.activeElement) return
      // 设置元素坐标
      state.activeElement.left = obj.left
      state.activeElement.top = obj.top
      // 设置元素大小
      state.activeElement.width = obj.width
      state.activeElement.height = obj.height

      state.activeElement.size = obj.size
    } catch (error) {
      throw error
    }
  },
  // ----------------------------------------------------------------------------------------
  /**
   * 临时文件
   */
  // 设置临时文件
  [M.SLIDEEDITOR.SetTemporaryFile] (state, obj) {
    try {
      // if (state.isPlay) {
      if (obj && obj.files.length && obj.texts.length && state.autoPlay === 'play') {
        this.commit(M.SLIDEEDITOR.SetAutoPlay, 'pause')
      }
      // state.isShowCover = obj.isCover;
      state.temporaryFile = obj
    } catch (error) {
      throw error
    }
  },
  // 设置临时文件大小比例
  [M.SLIDEEDITOR.SetTemporaryFileSize] (state, arr) {
    try {
      arr.forEach((item) => {
        let file = state.temporaryFile.files.find((x) => {
          return x.id === item.id
        })
        if (file) {
          file.width = item.width
          file.height = item.height
        }
      })
    } catch (error) {
      throw error
    }
  },
  // 设置标注轨迹
  [M.SLIDEEDITOR.SetTemporaryTrajectory] (state, arr) {
    try {
      if (state.isPlay) state.temporaryFile.trajectorys = arr
    } catch (error) {
      throw error
    }
  },
  // 设置临时文件滚动位置
  [M.SLIDEEDITOR.SetTemporaryScroll] (state, value) {
    try {
      state.temporaryFile.scroll = value
    } catch (error) {
      throw error
    }
  },
  // 设置临时投影区缩放图片
  [M.SLIDEEDITOR.SetTemporaryZoomImage] (context, url) {
    try {
      let zoomImage = {
        url: url,
        location: {left: 0, top: 0}
      }
      this._vm.$set(state.temporaryFile, 'zoomImage', zoomImage)
    } catch (error) {
      throw error
    }
  },
  // 设置临时投影区图片位置
  [M.SLIDEEDITOR.SetTemporaryZoomLocation] (context, loc) {
    try {
      if (state.temporaryFile.zoomImage.url) {
        state.temporaryFile.zoomImage.location = loc
      }
    } catch (error) {
      throw error
    }
  },
  // 设置临时投影区画笔状态
  [M.SLIDEEDITOR.SetTemporaryBrushState] (state, value) {
    try {
      if (value) state.temporaryFile.isZoom = false

      state.temporaryFile.isDraw = value
    } catch (error) {
      throw error
    }
  },
  // 设置临时投影区缩放状态
  [M.SLIDEEDITOR.SetTemporaryZoomState] (state, value) {
    try {
      if (value) state.temporaryFile.isDraw = false
      state.temporaryFile.isZoom = value
    } catch (error) {
      throw error
    }
  },
  // ---------------------------------------------------------------------------------------
  /**
   * 自定义配置
   */
  // 设置用户自定义属性
  [M.SLIDEEDITOR.SetCustomAttr] (state, obj) {
    try {
      if (state.customized[obj.attrName] === undefined) {
        this._vm.$set(state.customized, obj.attrName, obj.attrValue)
      } else {
        state.customized[obj.attrName] = obj.attrValue
      }
    } catch (error) {
      throw error
    }
  },
  // 设置用户自定义元素属性
  [M.SLIDEEDITOR.SetCustomElementAttr] (state, obj) {
    try {
      if (state.customized.DefaultElementStyle[obj.attrName] === undefined) {
        this._vm.$set(state.customized.DefaultElementStyle, obj.attrName, obj.attrValue)
      } else {
        state.customized.DefaultElementStyle[obj.attrName] = obj.attrValue
      }
    } catch (error) {
      throw error
    }
  },
  // 设置用户自定义标注属性
  [M.SLIDEEDITOR.SetCustomGraphAttr] (state, obj) {
    try {
      if (state.customized.DefaultGraphStyle[obj.attrName] === undefined) {
        this._vm.$set(state.customized.DefaultGraphStyle, obj.attrName, obj.attrValue)
      } else {
        state.customized.DefaultGraphStyle[obj.attrName] = obj.attrValue
      }
    } catch (error) {
      throw error
    }
  },
  // 设置用户自定义画笔属性
  [M.SLIDEEDITOR.SetCustomBrushAttr] (state, obj) {
    try {
      if (state.customized.DefaultBrush[obj.attrName] === undefined) {
        this._vm.$set(state.customized.DefaultBrush, obj.attrName, obj.attrValue)
      } else {
        state.customized.DefaultBrush[obj.attrName] = obj.attrValue
      }
    } catch (error) {
      throw error
    }
  },
  // 设置用户自定义动画属性
  [M.SLIDEEDITOR.SetCustomAnimationAttr] (state, obj) {
    try {
      for (let i = 0; i < obj.length; i++) {
        if (state.customized.DefaultAnimation[obj[i].attrName] === undefined) {
          this._vm.$set(state.customized.DefaultAnimation, obj[i].attrName, obj[i].attrValue)
        } else {
          state.customized.DefaultAnimation[obj[i].attrName] = obj[i].attrValue
        }
      }
    } catch (error) {
      throw error
    }
  },

  /**
   * 幻灯片模板
   */
  // 获取幻灯片模板和风格
  [M.SLIDEEDITOR.GetEditorCofing] (state, obj) {
    try {
      if (obj) {
        state.templates = obj.template
        state.styles = obj.style || []
        state.fontStyles = obj.font
        state.animations = obj.animation
        state.covers = obj.cover
        state.defaultFiles = obj.defaultFiles
      }

      let cover = S.LocalStore.getCustomizedCover()
      if (cover) {
        state.DefaultCover = cover.DefaultCover
        state.covers = state.covers.concat(cover.CustomizedCover)
      }
      let customizedCofig = S.LocalStore.getCustomizedCofig()
      if (customizedCofig) state.customized = {...state.customized, ...customizedCofig}
      let config = S.LocalStore.getEditorConfig()
      if (config) {
        state.DefaultBackground = config.DefaultBackground
        state.DefaultTemplate = config.DefaultTemplate
      }
      // 设置默认默认选中版式
      state.styles.forEach((item) => {
        if (!state.DefaultTemplate.find((x) => {
          return x.sid === item.id
        })) {
          let template = this.getters.template(item.id)
          state.DefaultTemplate.push({sid: item.id, id: template && template.length ? template[0].id : null})
        }
      })
    } catch (error) {
      throw error
    }
  },
  // 切换幻灯片模板
  async [M.SLIDEEDITOR.ChangeSlideTemplate] (state, id) {
    try {
      if (!state.slide) return
      let template = state.templates.find((item) => {
        return item.id === id
      })
      if (!template) return
      state.activeElement = null

      // 获取幻灯片模板
      template = JSON.parse(JSON.stringify(template.templateContent))
      // 获取当前幻灯片容器中所有元素对象
      let elements = JSON.parse(JSON.stringify(state.elements))
      elements = elements.sort((a, b) => {
        return a.index - b.index
      })

      // 获取风格元素
      let templateEls = elements
        .filter((x) => {
          return x.templateElement
        })
        .sort((a, b) => {
          return b.index - a.index
        })
      // 将风格元素添加到新的版式
      let maxIndex = templateEls.length
      templateEls.forEach((item, index) => {
        item.index = maxIndex
        item.name = item.type + item.index
        template.unshift(item)
        maxIndex--
      })
      maxIndex = templateEls.length

      let fileIDs = []

      // 循环幻灯片模板元素
      template.forEach((item) => {
        if (item.fileCode) fileIDs.push(item.fileCode)
        // 跳过填充模板元素
        if (!item.templateElement) {
          // 将现有内容填充至选中模板元素中
          for (let i = 0; i < elements.length; i++) {
            if (item.type !== elements[i].type || elements[i].templateElement) continue
            maxIndex++
            item.index = maxIndex
            item.name = item.type + item.index
            item.text = elements[i].text
            item.html = elements[i].html
            item.path = elements[i].path
            item.zoom = elements[i].zoom
            item.fileCode = elements[i].fileCode
            elements.splice(i, 1)
            break
          }
        }
      })
      elements.forEach((item) => {
        if (!item.templateElement) {
          maxIndex++
          item.index = maxIndex
          item.name = item.type + item.index
          template.push(item)
        }
      })

      if (template.length) {
        let files = null
        if (process.browser) {
          files = await this._vm.$api.post.GetEvidenceMaterial({
            sid: template[0].sid,
            files: fileIDs,
            dbPath: appearCourt.state.casePath
          })
        } else {
          files = await SQLite.GetEvidenceMaterial(fileIDs, template[0].sid)
        }

        state.files = state.files.concat(files)
      }
      state.elements = template
    } catch (error) {
      throw error
    }
  },
  // 切换幻灯片风格
  [M.SLIDEEDITOR.ChangeSlideStyle] (state, id) {
    try {
      if (!state.slide) return
      let style = state.styles.find((item) => {
        return item.id === id
      })
      if (!style) return
      state.activeElement = null

      style = JSON.parse(JSON.stringify(style.styleContent))
      // 删除当前编辑器中的风格
      for (let i = state.elements.length - 1; i >= 0; i--) {
        if (state.elements[i].templateElement) {
          state.elements.splice(i, 1)
        }
      }
      let index = style.length
      state.elements
        .sort((a, b) => {
          return a.index - b.index
        })
        .forEach((item) => {
          index++
          item.index = index
          item.name = item.type + item.index
        })
      index = style.length
      style.sort((a, b) => {
        return b.index - a.index
      }).forEach((item) => {
        item.index = index
        item.name = item.type + item.index
        state.elements.unshift(item)
        index--
      })
    } catch (error) {
      throw error
    }
  },
  // 保存幻灯版式
  [M.SLIDEEDITOR.SaveTemplates] (state, template) {
    try {
      state.templates.push(template)
    } catch (error) {
      throw error
    }
  },
  // 保存幻灯风格
  [M.SLIDEEDITOR.SaveStyles] (state, style) {
    try {
      state.styles.push(style)
    } catch (error) {
      throw error
    }
  },
  // ---------------------------------------------------------------------------------------
  /**
   * 编辑器图层
   */
  // 保存幻灯片风格
  [M.SLIDEEDITOR.ExchangeLayerOrder] (state, obj) {
    try {
      if (!obj || !obj.dragEl || !obj.dropEl || obj.dragEl === obj.dropEl) return

      // 获取交换元素
      let dragEl = state.elements.find((item) => {
        return item.id === obj.dragEl
      })
      let dropEl = state.elements.find((item) => {
        return item.id === obj.dropEl
      })

      if (!dragEl || !dropEl) return

      if (obj.exchangeType === 'exchange') {
        let dragElIndex = dragEl.index
        dragEl.index = dropEl.index
        dropEl.index = dragElIndex
      } else if (obj.exchangeType === 'before') {
        state.elements.filter((item) => {
          return item.index >= dropEl.index && item.index < dragEl.index
        }).forEach((item) => {
          item.index++
        })
        dragEl.index = dropEl.index - 1
      } else if (obj.exchangeType === 'after') {
        // 拖拽元素是否在接收元素之后
        let isAfter = dragEl.index > dropEl.index
        let dropElIndex = isAfter ? dropEl.index + 1 : dropEl.index

        // 调整两个交换元素之间的元素索引
        state.elements.filter((item) => {
          return isAfter ? (item.index > dropEl.index && item.index < dragEl.index) : (item.index <= dropEl.index && item.index > dragEl.index)
        }).forEach((item) => {
          item.index += isAfter ? 1 : -1
        })
        dragEl.index = dropElIndex
      }
    } catch (error) {
      throw error
    }
  },

  // ---------------------------------------------------------------------------------------
  /**
   * 遮罩层
   */
  // 设置编辑区画笔状态
  [M.SLIDEEDITOR.SetEditorBrushState] (state, obj) {
    try {
      if (obj.isDraw) state.maskCanvas.isZoom = false
      state.maskCanvas.isDraw = obj.isDraw
      state.maskCanvas.drawMode = obj.drawMode
    } catch (error) {
      throw error
    }
  },
  // 设置编辑区缩放状态
  [M.SLIDEEDITOR.SetEditorZoomState] (state, value) {
    try {
      if (value) state.maskCanvas.isDraw = false
      state.maskCanvas.isZoom = value
    } catch (error) {
      throw error
    }
  },
  // 设置遮罩标注
  [M.SLIDEEDITOR.SetMaskTrajectory] (state, arr) {
    try {
      state.maskCanvas.trajectorys = arr && Array.isArray(arr) ? arr : []
    } catch (error) {
      throw error
    }
  },
  // 设置遮罩缩放图片
  [M.SLIDEEDITOR.SetMaskZoomImage] (state, url) {
    try {
      let zoomImage = {
        url: url,
        location: {left: 0, top: 0}
      }
      state.maskCanvas.zoomImage = zoomImage
    } catch (error) {
      throw error
    }
  },
  // 设置遮罩缩放图片位置
  [M.SLIDEEDITOR.SetMaskZoomLocation] (state, loc) {
    try {
      if (state.maskCanvas.zoomImage.url) {
        state.maskCanvas.zoomImage.location = loc
      }
    } catch (error) {
      throw error
    }
  },

  // 添加元素文件
  [M.SLIDEEDITOR.AddElementFile] (state, arr) {
    try {
      for (let i = 0; i < arr.length; i++) {
        let file = arr[i]
        if (!file || !file.image || !file.image.length) continue
        for (let j = 0; j < file.image.length; j++) {
          let img = file.image[j]
          state.files.push({
            ID: img.id,
            IMG: img.base64
          })
        }
      }
    } catch (error) {
      throw error
    }
  },
  // 添加证据材料文件
  [M.SLIDEEDITOR.AddDossierFile] (state, arr) {
    try {
      state.files = state.files.concat(arr)
    } catch (error) {
      throw error
    }
  },
  // 添加外部文件
  [M.SLIDEEDITOR.AddExternalFile] (state, arr) {

  },
  // 删除外部文件
  [M.SLIDEEDITOR.DelExternalFile] (state, arr) {

  },

  // 添加回退状态
  [M.SLIDEEDITOR.AddFallbackState] (state, els) {
    state.isEditState = false
    // 回滚操作状态
    state.fallbackStates.push(els)
    state.currentStateIndex = state.fallbackStates.length - 1
    // console.log('已添加操作记录', state.fallbackStates)
  },
  // 前进下一编辑状态
  [M.SLIDEEDITOR.GoNextEditState] (state) {
    if (state.currentStateIndex + 1 >= state.fallbackStates.length) return
    for (let i = (state.currentStateIndex + 1); i < state.fallbackStates.length; i++) {
      if (JSON.stringify(state.elements) !== state.fallbackStates[i]) {
        state.currentStateIndex = i
        state.elements = JSON.parse(state.fallbackStates[i])
        break
      }
    }
    console.log('操作状态已前进')
  },
  // 回退上一编辑状态
  [M.SLIDEEDITOR.GoBackEditState] (state) {
    if (!state.fallbackStates.length || state.currentStateIndex < 0) return

    let els = JSON.stringify(state.elements).replace('"isEdit":true', '"isEdit":false')
    if (state.currentStateIndex + 1 === state.fallbackStates.length && state.fallbackStates[state.fallbackStates.length - 1] !== els) {
      state.fallbackStates.push(els)
    }
    for (let i = state.currentStateIndex; i >= 0; i--) {
      if (els !== state.fallbackStates[i]) {
        // console.log(state.fallbackStates[i])
        state.currentStateIndex = i === 0 ? -1 : i
        state.elements = JSON.parse(state.fallbackStates[i])
        break
      }
    }
    console.log('操作状态已回撤')
  },

  // 清理编辑区遮罩层
  [M.SLIDEEDITOR.ClearEditorMask] (state) {
    try {
      // state.isZoomEditor = false;
      state.maskCanvas = {trajectorys: [], zoomImage: {}, isDraw: false, isZoom: false, drawMode: 'FreeLine'}
    } catch (error) {
      throw error
    }
  },
  // 设置编辑器缩放对象
  [M.SLIDEEDITOR.SetEditorZoomAttr] (state, obj) {
    try {
      if (obj.attrName === 'isZoom' && !obj.attrValue) {
        state.zoomImage = {isZoom: false, isDraw: false, image: null, width: 0, height: 0, left: 0, top: 0, sign: []}
        return
      }
      if (!Array.isArray(obj)) obj = [obj]

      obj.forEach((item) => {
        state.zoomImage[item.attrName] = item.attrValue
      })
    } catch (error) {
      throw error
    }
  },
  // 添加编辑器缩放区标注
  [M.SLIDEEDITOR.AddEditorZoomSign] (state) {
    try {
      state.zoomImage.sign.push([])
    } catch (error) {
      throw error
    }
  },
  // 添加编辑器缩放区标注坐标
  [M.SLIDEEDITOR.AddEditorZoomSignLocation] (state, loc) {
    try {
      if (state.zoomImage.sign.length) {
        state.zoomImage.sign[state.zoomImage.sign.length - 1].push(loc)
      } else {
        state.zoomImage.sign.push([loc])
      }
    } catch (error) {
      throw error
    }
  },
  // 添加编辑器缩放区标注坐标
  [M.SLIDEEDITOR.RemoveEditorZoomSign] (state) {
    try {
      for (let i = state.zoomImage.sign.length - 1; i >= 0; i--) {
        let item = state.zoomImage.sign[i]
        if (!item.length) {
          state.zoomImage.sign.splice(i, 1)
        } else {
          state.zoomImage.sign.splice(i, 1)
          break
        }
      }
    } catch (error) {
      throw error
    }
  },
  // 清除编辑器缩放区所有标注坐标
  // [M.SLIDEEDITOR.RemoveEditorZoomSignAll] (state) {
  //   try {
  //     for (let i = state.zoomImage.sign.length - 1; i >= 0; i--) {
  //       let item = state.zoomImage.sign[i]
  //       if (!item.length) {
  //         state.zoomImage.sign.splice(i, 1)
  //       } else {
  //         state.zoomImage.sign.splice(i, 1)
  //       }
  //     }
  //   } catch (error) {
  //     throw error
  //   }
  // },
  // 清理编辑区
  [M.SLIDEEDITOR.ClearSlideEditor] (state) {
    state.isEditState = false
    state.isEditSlide = false
    state.slide = null
    state.currentStateIndex = 0
    state.fallbackStates = []
    state.elements = []
    state.files = []
    state.templates = null
    state.styles = []
    state.activeElement = null
    state.defaultElement = null
    state.copyElement = null
    state.isPlay = false
    state.autoPlay = null
    state.preview = false
    state.isCropImage = false
    state.isShowCover = false
    // this.dispatch(A.SLIDEEDITOR.SetCoverShowState, false);
    state.temporaryFile = {files: [], texts: [], trajectorys: [], scroll: 0, drawMode: 'FreeLine'}

    // this._vm.$electron.ipcRenderer.send("window-close", { id: "SlideExpandScreen" })
  }
}
const actions = {
  /**
   * 公用属性
   */
  // 设置状态
  [A.SLIDEEDITOR.SetState] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.SetState, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      // this._vm.$alert("同步幻灯片状态时出现了一个意料之外的错误")
    }
  },
  // 设置状态属性
  [A.SLIDEEDITOR.SetStateAttr] (context, obj) {
    try {
      if (!Array.isArray(obj)) obj = [obj]
      context.commit(M.SLIDEEDITOR.SetStateAttr, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置幻灯片状态时出现了一个意料之外的错误')
    }
  },
  // 设置鼠标状态
  [A.SLIDEEDITOR.SetCursorState] (context, value) {
    try {
      context.commit(M.SLIDEEDITOR.SetCursorState, value)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置鼠标状态时出现了一个意料之外的错误')
    }
  },
  // 设置预览状态
  [A.SLIDEEDITOR.SetPreviewState] (context, value) {
    try {
      context.commit(M.SLIDEEDITOR.SetPreviewState, value)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('预览幻灯片时出现了一个意料之外的错误')
    }
  },
  // 设置播放状态
  async [A.SLIDEEDITOR.SetPlayState] (context, value) {
    try {
      if (value && !context.state.isPlay) {
        await context.dispatch(A.SLIDEEDITOR.SetSlideAttr,
          {
            attrName: 'slides',
            attrValue: value ? getPlaySlide(evidenceCatalog.state.evidenceCatalogTreeData) : []
          })
        if (!context.state.slides.length) {
          this._vm.$alert('放映失败：未找到任何放映内容')
          return
        }
        if (!context.state.slide) {
          await this.dispatch(A.SLIDEEDITOR.InitSlide, context.state.slides[0])
        }
      }

      context.commit(M.SLIDEEDITOR.SetPlayState, value)
      if (value) {
        // context.rootState.preplan.evidenceCatalogTreeData
        // context.dispatch(A.SLIDEEDITOR.SetCoverShowState, true);
      } else {
        context.dispatch(A.SLIDEEDITOR.SetEditorZoomAttr, {
          attrName: 'isZoom',
          attrValue: false
        })
        context.dispatch(A.SLIDEEDITOR.SetTemporaryFile)
        context.dispatch(A.SLIDEEDITOR.SetCoverShowState, false)
      }
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('播放幻灯片时出现了一个意料之外的错误')
    }
  },
  // 设置自动播放
  [A.SLIDEEDITOR.SetAutoPlay] (context, value) {
    try {
      context.commit(M.SLIDEEDITOR.SetAutoPlay, value)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('自动播放时出现了一个意料之外的错误')
    }
  },

  /**
   * 幻灯片对象
   */
  // 初始化幻灯片
  async [A.SLIDEEDITOR.InitSlide] (context, evidenceCatalog) {
    try {
      context.commit('SET_LOADINGCASE', {loading: true, loadingText: '正在初始化幻灯片，请稍候...'})
      context.dispatch(A.SLIDEEDITOR.SetStateAttr, {attrName: 'fallbackStates', attrValue: []})
      context.dispatch(A.SLIDEEDITOR.SetEditorZoomAttr, {attrName: 'isZoom', attrValue: false})

      context.dispatch(A.SLIDEEDITOR.SetCursorState)
      let slide = null
      if (evidenceCatalog) {
        let parentNode = evidenceCatalog.parent
        if (parentNode && parentNode.data) {
          parentNode = parentNode.data.alias
        }
        evidenceCatalog = evidenceCatalog.data
        slide = {
          id: evidenceCatalog.id,
          sid: evidenceCatalog.style,
          tid: evidenceCatalog.template,
          element: [],
          files: []
        }
        // let fileIDs = await editorServer.getSlideImgIDs(slide.id)
        // let ids = fileIDs.length || !evidenceCatalog.fileID ? [] : [evidenceCatalog.fileID]
        let video = []
        // for (let i = 0; i < fileIDs.length; i++) {
        //   if (process.browser && fileIDs[i].sffj === 'Y') video.push(`'${fileIDs[i].id}'`)
        //   ids.push(fileIDs[i].wjxh)
        // }
        console.time('获取证件材料')
        let files = null
        if (process.browser) {
          files = await this._vm.$api.post.GetEvidenceMaterial({
            sid: slide.id,
            files: [evidenceCatalog.fileID],
            dbPath: context.rootState.appearCourt.casePath
          })
          if (files) {
            let media = files.filter(x => /\.mp4/i.test(x.IMG) || /\.mp3/i.test(x.IMG))
            for (let i = 0; i < media.length; i++) {
              let access = await this._vm.$api.post.getCaseAccessories(media[i].WJID)
              if (!access) continue
              media[i].IMG = access.wjlj
            }
          }
        } else {
          files = await SQLite.GetEvidenceMaterial([evidenceCatalog.fileID], slide.id)
        }
        console.timeEnd('获取证件材料')

        if (files && slide.sid && slide.tid) {
          slide.element.push({
            type: 'TEXT',
            html: context.state.customized.AutoAddCatalog && Number(evidenceCatalog.type) !== 2 ? `${parentNode}/${evidenceCatalog.alias}` : evidenceCatalog.alias,
            text: context.state.customized.AutoAddCatalog && Number(evidenceCatalog.type) !== 2 ? `${parentNode}/${evidenceCatalog.alias}` : evidenceCatalog.alias,
            path: ''
          })

          // if (evidenceCatalog.fileID) {
          slide.tid = evidenceCatalog.template
          // let video = []
          for (let j = 0; j < files.length; j++) {
            let item = files[j]
            if (evidenceCatalog.fileType === 'MEDIA' || evidenceCatalog.fileType === 'AUDIO') {
              if (process.browser) video.push(`'${item.ID}'`)
              slide.element.push(
                {
                  type: evidenceCatalog.fileType,
                  orientation: 'left',
                  distance: 0.1,
                  top: 0.15,
                  left: 0.1,
                  size: {width: 0.8, height: 0.8},
                  path: item.ID,
                  fileID: item.WJID
                })
            } else {
              slide.element.push(
                {
                  type: evidenceCatalog.fileType,
                  orientation: 'left',
                  distance: j === 0 ? 0.05 : 0,
                  path: item.ID,
                  fileID: item.WJID
                })
            }

            slide.element[slide.element.length - 1].html = slide.element[0].html
            slide.element[slide.element.length - 1].text = slide.element[0].text
          }
          files = files.concat(context.state.defaultFiles)
        }
        // if (video.length) {
        //   for (let i = 0; i < video.length; i++) {
        //
        //     let res = await this._vm.$api.post.getCaseAccessories({
        //       AJID: context.rootState.appearCourt.caseID,
        //       IDS: video.join(',')
        //     })
        //   }
        //   // for (let i = 0; i < res.length; i++) {
        //   //   let index = files.findIndex(x => x.ID === res[i].ID)
        //   //   if (index >= 0) files[index] = res[i]
        //   // }
        // }
        slide.files = files
      }

      await context.dispatch(A.SLIDEEDITOR.SetSlideProps, slide)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('初始化幻灯片时出现了一个意料之外的错误')
    } finally {
      context.commit('SET_LOADINGCASE', {loading: false})
    }
  },
  // 设置幻灯片标题
  async [A.SLIDEEDITOR.SetSlideTitle] (context, obj) {
    try {
      context.commit('SET_LOADINGCASE', {loading: true, loadingText: '正在编辑幻灯片标题，请稍等...'})
      await editorServer.eidtSlideTitle(obj)
      if (context.state.slide && context.state.slide.id === obj.id) {
        context.commit(M.SLIDEEDITOR.SetSlideTitle, obj.text)
      }
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置幻灯片标题时出现了一个意料之外的错误')
    } finally {
      context.commit('SET_LOADINGCASE', {loading: false})
    }
  },

  /**
   * 幻灯片对象
   */
  // 设置幻灯片参数
  async [A.SLIDEEDITOR.SetSlideProps] (context, obj) {
    try {
      await context.dispatch(A.SLIDEEDITOR.SaveSlideElement)
      context.commit(M.SLIDEEDITOR.SetSlideProps, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('初始化幻灯片参数时出现了一个意料之外的错误')
    }
  },
  // 初始化幻灯片
  async [A.SLIDEEDITOR.InitSlideElement] ({state, commit, rootState}) {
    try {
      let slide = state.slide
      if (!slide) return
      // 幻灯片版式
      let template = await editorServer.getSlideElements(slide.id)
      let content = null
      if (!template || !template.length) {
        template = state.templates.find((item) => {
          return item.id === slide.tid
        })
        template = template && template.templateContent ? JSON.parse(JSON.stringify(template.templateContent)) : []
        content = slide.element
      }

      content = content ? JSON.parse(JSON.stringify(content)) : []
      let elements = getSlideElements(template, content, state.customized)
      commit(M.SLIDEEDITOR.SetSlideElement, {els: elements, files: slide.files})
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('初始化幻灯片内容时出现了一个意料之外的错误')
    } finally {
      commit('SET_LOADINGCASE', {loading: false})
    }
  },
  // 设置幻灯片元素
  [A.SLIDEEDITOR.SetSlideElement] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.SetSlideElement, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置幻灯片元素时出现了一个意料之外的错误')
    }
  },
  // 设置幻灯片属性
  [A.SLIDEEDITOR.SetSlideAttr] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.SetSlideAttr, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置幻灯片属性状态时出现了一个意料之外的错误')
    }
  },
  // 保存幻灯片元素
  [A.SLIDEEDITOR.SaveSlideElement] (context) {
    return new Promise(async (resolve, reject) => {
      try {
        let slide = context.state.slide
        if (slide && context.state.isEditSlide && !context.state.expandScreen) {
          let elements = state.elements.filter((x) => {
            return !x.templateElement
          })

          await editorServer.saveSlide({
            id: slide.id,
            elements: JSON.parse(JSON.stringify(elements))
          })
          context.dispatch(A.SLIDEEDITOR.SetStateAttr, {attrName: 'isEditSlide', attrValue: false})
          // this._vm.$electron.ipcRenderer.send(ipcs.MAIN.generateEditorThumb, {
          //     slide: slide
          // });
        }
        resolve()
      } catch (error) {
        reject(error)
      }
    })
  },
  // 设置幻灯片风格
  [A.SLIDEEDITOR.SetSlideStyle] (context, value) {
    try {
      context.commit(M.SLIDEEDITOR.SetSlideStyle, value)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置幻灯片背景时出现了一个意料之外的错误')
    }
  },
  // 设置幻灯片版式
  [A.SLIDEEDITOR.SetSlideTempalte] (context, value) {
    try {
      context.commit(M.SLIDEEDITOR.SetSlideTempalte, value)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置幻灯片版式时出现了一个意料之外的错误')
    }
  },
  // ----------------------------------------------------------
  /**
   * 封面
   */
  // 添加封面
  [A.SLIDEEDITOR.AddCover] (context, filePath) {
    try {
      context.commit(M.SLIDEEDITOR.AddCover, filePath)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('添加封面时出现了一个意料之外的错误')
    }
  },
  // 设置封面文本
  async [A.SLIDEEDITOR.SetCoverText] (context, text) {
    try {
      let defaultCover = context.getters.defaultCover
      // 修改内置模板
      if (!defaultCover.isCustom) {
        SQLite.SetCoverTemplate({id: defaultCover.id, coverText: text})
      }
      context.commit(M.SLIDEEDITOR.SetCoverText, text)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置封面文本时出现了一个意料之外的错误')
    }
  },
  // 设置选中封面
  async [A.SLIDEEDITOR.SetSelectedCover] (context, id) {
    try {
      context.commit(M.SLIDEEDITOR.SetSelectedCover, id)
      // await SQLite.SetCoverBackground({ image: context.getters.defaultCover.coverImage });
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置默认封面时出现了一个意料之外的错误')
    }
  },

  // 设置封面显示状态
  [A.SLIDEEDITOR.SetCoverShowState] (context, value) {
    try {
      if (value && state.autoPlay === 'play') {
        context.dispatch(A.SLIDEEDITOR.SetAutoPlay, 'pause')
      }
      context.commit(M.SLIDEEDITOR.SetCoverShowState, value)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置封面显示时出现了一个意料之外的错误')
    }
  },
  // --------------------------------------------------------------------------------------------
  /**
   * 编辑器背景
   */
  // 添加编辑器背景
  [A.SLIDEEDITOR.AddBackgroundImage] (state, arr) {
  },
  // 设置默认背景
  [A.SLIDEEDITOR.SetSelectedBackground] (context, id) {
    try {
      context.commit(M.SLIDEEDITOR.SetSelectedBackground, id)

      let template = context.state.DefaultTemplate.find((x) => {
        return x.sid === id
      })
      if (!template || !template.id) {
        let data = context.getters.template(id)
        template = {sid: id, id: data && data.length ? data[0].id : null}
      }

      context.dispatch(A.SLIDEEDITOR.SetSelectedTemplate, template)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置默认背景时出现了一个意料之外的错误')
    }
  },
  /**
   * 编辑器版式
   */
  // 设置默认背景
  [A.SLIDEEDITOR.SetSelectedTemplate] (context, id) {
    try {
      context.commit(M.SLIDEEDITOR.SetSelectedTemplate, id)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置默认版式时出现了一个意料之外的错误')
    }
  },
  // --------------------------------------------------------------------------------------------
  /**
   * 元素对象
   */
  // 添加幻灯片元素
  [A.SLIDEEDITOR.AddSlideElements] (context, arr) {
    try {
      context.commit(M.SLIDEEDITOR.AddSlideElements, arr)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('添加幻灯片元素时出现了一个意料之外的错误')
    }
  },
  // 添加活动元素
  [A.SLIDEEDITOR.AddActiveElement] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.AddActiveElement, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('添加活动元素时出现了一个意料之外的错误')
    }
  },
  // 设置添加默认元素
  [A.SLIDEEDITOR.SetDefaultElement] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.SetDefaultElement, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置默认元素时出现了一个意料之外的错误')
    }
  },
  // 设置活动元素
  [A.SLIDEEDITOR.SetActiveElement] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.SetActiveElement, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置活动元素时出现了一个意料之外的错误')
    }
  },
  // 复制元素
  [A.SLIDEEDITOR.CopyElement] (context) {
    try {
      if (!context.state.activeElement) return
      context.commit(M.SLIDEEDITOR.CopyElement)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('复制元素时出现了一个意料之外的错误')
    }
  },
  // 复制粘贴元素
  [A.SLIDEEDITOR.PasteElement] (context) {
    try {
      if (!context.state.copyElement) return
      context.commit(M.SLIDEEDITOR.PasteElement)
      this._vm.$eventBus.$emit('pointerup')
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('粘贴元素时出现了一个意料之外的错误')
    }
  },
  // 删除活动元素
  [A.SLIDEEDITOR.DelActiveElement] ({state, dispatch, commit}, id) {
    try {
      if (!state.elements) return
      let el = id ? state.elements.find((x) => {
        return x.id === id
      }) : state.activeElement
      if (!el || el.isEdit) return

      let delEls = [el.id]
      // let delImgs = []
      // if (el.type === 'IMAGE') {
      //   await editorServer.delExternalFileStream({WJID: el.fileCode, ID: el.path})
      //   delImgs.push({WJID: el.fileCode, ID: el.path})
      // }
      commit(M.SLIDEEDITOR.DelActiveElement, delEls)

      this._vm.$eventBus.$emit('pointerup')
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('删除选中元素时出现了一个意料之外的错误')
    }
  },
  // 设置元素属性
  [A.SLIDEEDITOR.SetElementAttr] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.SetElementAttr, obj)
    } catch (error) {
      console.error(error)
      this._vm.$alert('设置元素状态时出现了一个意料之外的错误')
    }
  },
  // 添加外部文档
  [A.SLIDEEDITOR.AddDocument] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.AddDocument, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('添加外部文档时出现了一个意料之外的错误')
    }
  },
  // 设置元素编辑状态
  [A.SLIDEEDITOR.SetElementEidtState] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.SetElementEidtState, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置编辑状态时出现了一个意料之外的错误')
    }
  },
  // 设置文本元素图片
  [A.SLIDEEDITOR.SetTextElementImage] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.SetTextElementImage, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置文本元素图片时出现了一个意料之外的错误')
    }
  },
  // --------------------------------------------------------------------------------------------
  /**
   * 元素动画
   */
  // 添加元素进入动画
  [A.SLIDEEDITOR.AddElementAnimation] (context, animationName) {
    try {
      context.commit(M.SLIDEEDITOR.AddElementAnimation, animationName)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('添加元素动画时出现了一个意料之外的错误')
    }
  },
  // 删除元素进入动画
  [A.SLIDEEDITOR.DelElementAnimation] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.DelElementAnimation, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('删除元素动画时出现了一个意料之外的错误')
    }
  },
  // 上一动画
  [A.SLIDEEDITOR.PreviousAnimation] (context) {
    try {
      context.dispatch(A.SLIDEEDITOR.SetEditorZoomState, false)
      context.commit(M.SLIDEEDITOR.PreviousAnimation)
      this.dispatch(A.SLIDEEDITOR.SetCoverShowState, false)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('切换上一幻灯片或动画时出现了一个意料之外的错误')
    }
  },
  // 下一动画
  [A.SLIDEEDITOR.NextAnimation] (context, isFristExec) {
    try {
      context.dispatch(A.SLIDEEDITOR.SetEditorZoomState, false)
      context.commit(M.SLIDEEDITOR.NextAnimation, isFristExec)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('切换下一幻灯片或动画时出现了一个意料之外的错误')
    }
  },
  // --------------------------------------------------------------------------------------------
  /**
   * 元素内容
   */
  // 设置活动元素属性
  [A.SLIDEEDITOR.SetActiveElementAttr] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.SetActiveElementAttr, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置活动元素状态时出现了一个意料之外的错误')
    }
  },
  // 设置活动元素字体样式
  [A.SLIDEEDITOR.SetActiveElementFont] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.SetActiveElementFont, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置活动元素字体时出现了一个意料之外的错误')
    }
  },
  // 设置活动元素位置和大小
  [A.SLIDEEDITOR.SetActiveEleLocAndSize] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.SetActiveEleLocAndSize, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置活动元素位置大小时出现了一个意料之外的错误')
    }
  },
  // --------------------------------------------------------------------------------------------
  /**
   * 临时文件
   */
  // 设置临时文件
  [A.SLIDEEDITOR.SetTemporaryFile] (context, obj) {
    try {
      let temporaryFile = {
        files: [],
        texts: [],
        trajectorys: [],
        scroll: 0,
        isDraw: false,
        isZoom: false,
        drawMode: 'FreeLine'
      }
      if (obj && !obj.isCover && context.state.isShowCover) {
        context.dispatch(A.SLIDEEDITOR.SetCoverShowState, false)
      }
      if (!obj) {
        this.dispatch(A.SLIDEEDITOR.SetCursorState, null)
      } else if (typeof obj === 'string') {
        temporaryFile.files = [{id: uuid(), url: obj}]
      } else if (Array.isArray(obj)) {
        obj.forEach((item) => {
          temporaryFile.files.push({id: uuid(), url: item})
        })
      } else if (typeof obj === 'object') {
        temporaryFile.files = obj.files
        temporaryFile.texts = obj.texts
      }
      context.commit(M.SLIDEEDITOR.SetTemporaryFile, temporaryFile)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置临时文件时出现了一个意料之外的错误')
    }
  },
  // 设置临时文件大小比例
  [A.SLIDEEDITOR.SetTemporaryFileSize] (context, arr) {
    try {
      context.commit(M.SLIDEEDITOR.SetTemporaryFileSize, arr)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置临时文件大小时出现了一个意料之外的错误')
    }
  },
  // 设置标注轨迹
  [A.SLIDEEDITOR.SetTemporaryTrajectory] (context, arr) {
    try {
      context.commit(M.SLIDEEDITOR.SetTemporaryTrajectory, arr)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('添加临时文件标注时出现了一个意料之外的错误')
    }
  },
  // 设置临时文件滚动位置
  [A.SLIDEEDITOR.SetTemporaryScroll] (context, value) {
    try {
      context.commit(M.SLIDEEDITOR.SetTemporaryScroll, value)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置临时文件滚动位置时出现了一个意料之外的错误')
    }
  },
  // 设置临时投影区缩放图片
  [A.SLIDEEDITOR.SetTemporaryZoomImage] (context, url) {
    context.commit(M.SLIDEEDITOR.SetTemporaryZoomImage, url)
  },
  // 设置临时投影区图片位置
  [A.SLIDEEDITOR.SetTemporaryZoomLocation] (context, loc) {
    context.commit(M.SLIDEEDITOR.SetTemporaryZoomLocation, loc)
  },
  // 设置临时投影区画笔状态
  [A.SLIDEEDITOR.SetTemporaryBrushState] (context, value) {
    try {
      context.commit(M.SLIDEEDITOR.SetTemporaryBrushState, value)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置临时文件画笔状态时出现了一个意料之外的错误')
    }
  },
  // 设置临时投影区缩放状态
  [A.SLIDEEDITOR.SetTemporaryZoomState] (context, value) {
    context.commit(M.SLIDEEDITOR.SetTemporaryZoomState, value)
  },
  // ---------------------------------------------------------------------------------------
  /**
   * 自定义配置
   */
  // 设置用户自定义属性
  [A.SLIDEEDITOR.SetCustomAttr] (context, obj) {
    context.commit(M.SLIDEEDITOR.SetCustomAttr, obj)
  },
  // 设置用户自定义元素属性
  [A.SLIDEEDITOR.SetCustomElementAttr] (context, obj) {
    context.commit(M.SLIDEEDITOR.SetCustomElementAttr, obj)
  },
  // 设置用户自定义标注属性
  [A.SLIDEEDITOR.SetCustomGraphAttr] (context, obj) {
    context.commit(M.SLIDEEDITOR.SetCustomGraphAttr, obj)
  },
  // 设置用户自定义标注属性
  [A.SLIDEEDITOR.SetCustomBrushAttr] (context, obj) {
    context.commit(M.SLIDEEDITOR.SetCustomBrushAttr, obj)
  },
  // 设置用户自定义动画属性
  [A.SLIDEEDITOR.SetCustomAnimationAttr] (context, obj) {
    if (typeof obj === 'object' && !Array.isArray(obj)) obj = [obj]
    context.commit(M.SLIDEEDITOR.SetCustomAnimationAttr, obj)
  },
  // --------------------------------------------------------------------------------------------
  /**
   * 幻灯片模板
   */
  // 获取幻灯片模板和风格
  async [A.SLIDEEDITOR.GetEditorCofing] (context) {
    try {
      let config = await editorServer.getSlideConfig()
      config.cover.forEach((item) => {
        item.coverText = item.coverText ? item.coverText : context.rootState.mainPage.userInfo.unitName
      })
      context.commit(M.SLIDEEDITOR.GetEditorCofing, config)
    } catch (error) {
      this._vm.$alert(error.message, '读取幻灯片编辑器配置错误')
    }
  },
  // 切换幻灯片模板
  [A.SLIDEEDITOR.ChangeSlideTemplate] (context, id) {
    try {
      context.commit(M.SLIDEEDITOR.ChangeSlideTemplate, id)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('切换幻灯片版式时出现了一个意料之外的错误')
    }
  },
  // 切换幻灯片风格
  [A.SLIDEEDITOR.ChangeSlideStyle] (context, id) {
    try {
      context.commit(M.SLIDEEDITOR.ChangeSlideStyle, id)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('切换幻灯片背景时出现了一个意料之外的错误')
    }
  },
  // 保存幻灯片版式
  [A.SLIDEEDITOR.SaveTemplates] (context, templateName) {
    return new Promise(async (resolve, reject) => {
      try {
        let templateEls = state.elements.filter((x) => {
          return !x.templateElement
        })
        if (!templateEls.length) {
          throw new Error('没有找到版式元素')
        }

        if (state.templates.find((item) => {
          return item.templateName === templateName
        })) {
          throw new Error('已存在相同版式名称')
        }

        templateEls = JSON.parse(JSON.stringify(templateEls))
        // 清除元素内容
        templateEls.forEach((item) => {
          item.text = item.html = item.path = ''
        })

        let parameter = {id: uuid(), templateName: templateName}
        await editorServer.addSlideTemplate({...parameter, elements: templateEls})
        // 添加幻灯片版式
        context.commit(M.SLIDEEDITOR.SaveTemplates, {...parameter, templateContent: templateEls})
        resolve()
      } catch (error) {
        reject(error)
      }
    })
  },
  // 保存幻灯片风格
  [A.SLIDEEDITOR.SaveStyles] (context, styleName) {
    return new Promise(async (resolve, reject) => {
      try {
        let styleEls = state.elements.filter((x) => {
          return x.templateElement
        })
        if (!styleEls.length) {
          throw new Error('没有找到风格元素')
        }

        if (state.styles.find((item) => {
          return item.styleName === styleName
        })) {
          throw new Error('已存在相同风格名称')
        }

        styleEls = JSON.parse(JSON.stringify(styleEls))
        let parameter = {id: uuid(), styleName: styleName}
        await editorServer.addSlideStyle({...parameter, elements: styleEls})
        // 添加幻灯片风格
        context.commit(M.SLIDEEDITOR.SaveStyles, {...parameter, styleContent: styleEls})
        resolve()
      } catch (error) {
        reject(error)
      }
    })
  },
  // ---------------------------------------------------------------------------------------
  /**
   * 编辑器图层
   */
  // 保存幻灯片风格
  [A.SLIDEEDITOR.ExchangeLayerOrder] (context, obj) {
    context.commit(M.SLIDEEDITOR.ExchangeLayerOrder, obj)
  },
  // ---------------------------------------------------------------------------------------
  /**
   * 遮罩层
   */
  // 设置编辑区画笔状态
  [A.SLIDEEDITOR.SetEditorBrushState] (context, obj) {
    try {
      context.commit(M.SLIDEEDITOR.SetEditorBrushState, obj)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('设置幻灯片标注状态时出现了一个意料之外的错误')
    }
  },
  // 设置编辑区缩放状态
  [A.SLIDEEDITOR.SetEditorZoomState] (context, value) {
    context.commit(M.SLIDEEDITOR.SetEditorZoomState, value)
  },
  // 设置遮罩标注
  [A.SLIDEEDITOR.SetMaskTrajectory] (context, arr) {
    try {
      context.commit(M.SLIDEEDITOR.SetMaskTrajectory, arr)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('添加幻灯片标注时出现了一个意料之外的错误')
    }
  },
  // 设置遮罩缩放图片
  [A.SLIDEEDITOR.SetMaskZoomImage] (context, url) {
    context.commit(M.SLIDEEDITOR.SetMaskZoomImage, url)
  },
  // 设置遮罩缩放图片位置
  [A.SLIDEEDITOR.SetMaskZoomLocation] (context, loc) {
    context.commit(M.SLIDEEDITOR.SetMaskZoomLocation, loc)
  },

  // 添加元素文件
  [A.SLIDEEDITOR.AddElementFile] (context, arr) {
    try {
      context.commit(M.SLIDEEDITOR.AddElementFile, arr)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('添加元素文件时出现了一个意料之外的错误')
    }
  },
  // 添加证据材料文件
  [A.SLIDEEDITOR.AddDossierFile] (context, arr) {
    try {
      context.commit(M.SLIDEEDITOR.AddDossierFile, arr)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('添加证件材料时出现了一个意料之外的错误')
    }
  },
  // 添加外部文件
  async [A.SLIDEEDITOR.AddExternalFile] (context, obj) {
    try {
      let fileName = ''
      if (process.browser) {
        context.dispatch(A.SLIDEEDITOR.AddDossierFile, obj.file.Files)
        context.dispatch(A.SLIDEEDITOR.SetElementAttr,
          [
            {id: obj.id, attrName: 'fileCode', attrValue: obj.file.ID},
            {id: obj.id, attrName: 'path', attrValue: obj.file.Files[0].ID},
            {id: obj.id, attrName: 'text', attrValue: obj.file.FilePath},
            {id: obj.id, attrName: 'html', attrValue: obj.file.FilePath}
          ]
        )
      } else {
        fileName = path.basename(obj.path)
        obj.path = [obj.path]
        let result = await SQLite.DocumentConvertToImage(obj.path)
        if (!result) throw new Error('未获取返回文件')
        if (!result.length) return
        result = result[0]
        if (result.ErrorMessage) throw new Error(`添加文件失败：${result.ErrorMessage}`)
        let files = []
        result.Files.forEach((item) => {
          files.push({ID: item.ID, IMG: item.Image})
        })
        context.dispatch(A.SLIDEEDITOR.AddDossierFile, files)
        context.dispatch(A.SLIDEEDITOR.SetElementAttr,
          [
            {id: obj.id, attrName: 'fileCode', attrValue: result.ID},
            {id: obj.id, attrName: 'path', attrValue: result.Files[0].ID},
            {id: obj.id, attrName: 'text', attrValue: fileName},
            {id: obj.id, attrName: 'html', attrValue: fileName}
          ]
        )
      }
      // if (obj.fileID && obj.imageID) editorServer.delExternalFileStream({WJID: obj.fileID, ID: obj.imageID})
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('添加外部文件时出现了一个意料之外的错误')
    }
  },
  // 删除外部文件
  [A.SLIDEEDITOR.DelExternalFile] (context, arr) {

  },

  // 添加回退状态
  [A.SLIDEEDITOR.AddFallbackState] (context, els) {
    els = els.replace('"isEdit":true', '"isEdit":false')
    if (state.fallbackStates.length && state.fallbackStates[state.currentStateIndex] === els) return
    context.commit(M.SLIDEEDITOR.AddFallbackState, els)
  },
  // 前进下一编辑状态
  [A.SLIDEEDITOR.GoNextEditState] (context) {
    if (context.state.currentStateIndex + 1 >= context.state.fallbackStates.length) return
    context.commit(M.SLIDEEDITOR.GoNextEditState)
  },
  // 回退上一编辑状态
  [A.SLIDEEDITOR.GoBackEditState] (context) {
    if (!context.state.fallbackStates.length || context.state.currentStateIndex < 0) return
    context.commit(M.SLIDEEDITOR.GoBackEditState)
  },

  // 清理编辑区遮罩层
  [A.SLIDEEDITOR.ClearEditorMask] (context) {
    try {
      context.commit(M.SLIDEEDITOR.ClearEditorMask)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('清理幻灯片遮罩时出现了一个意料之外的错误')
    }
  },
  // 设置编辑器缩放对象
  [A.SLIDEEDITOR.SetEditorZoomAttr] (context, obj) {
    // 清除放大区域所有标注
    // context.commit(M.SLIDEEDITOR.RemoveEditorZoomSignAll)
    context.commit(M.SLIDEEDITOR.SetEditorZoomAttr, obj)
  },
  // 添加编辑器缩放区标注
  [A.SLIDEEDITOR.AddEditorZoomSign] (context) {
    try {
      context.commit(M.SLIDEEDITOR.AddEditorZoomSign)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('添加放大区域标注时出现了一个意料之外的错误')
    }
  },
  // 添加编辑器缩放区标注坐标
  [A.SLIDEEDITOR.AddEditorZoomSignLocation] (context, loc) {
    try {
      context.commit(M.SLIDEEDITOR.AddEditorZoomSignLocation, loc)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('添加放大区域标注坐标时出现了一个意料之外的错误')
    }
  },
  // 添加编辑器缩放区标注坐标
  [A.SLIDEEDITOR.RemoveEditorZoomSign] (context) {
    try {
      context.commit(M.SLIDEEDITOR.RemoveEditorZoomSign)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('清除放大区域标注时出现了一个意料之外的错误')
    }
  },
  // 清理编辑区
  async [A.SLIDEEDITOR.ClearSlideEditor] (context) {
    try {
      if (this._vm.$electron) this._vm.$electron.ipcRenderer.send(ipcs.MAIN.closeExpandScreen)
      await context.dispatch(A.SLIDEEDITOR.SaveSlideElement)
      context.dispatch(A.SLIDEEDITOR.SetEditorZoomAttr, {attrName: 'isZoom', attrValue: false})
      context.commit(M.SLIDEEDITOR.ClearSlideEditor)
    } catch (error) {
      console.error(error)
      this._vm.$logger.error(error.message)
      this._vm.$alert('释放编辑区时出现了一个意料之外的错误')
    }
  }
}
const getters = {
  // 编辑器元素
  elements: function (state, getters) {
    let elements = state.elements.filter((x) => {
      if (!state.isPlay && !state.preview) return true

      if (x.templateElement || x.type === 'STRAGHTLINE' || x.type === 'RECTANGLE' || x.type === 'ELLIPSE') return true

      return !!(x.html || x.text || x.path)
    }).sort((a, b) => {
      return a.index - b.index
    })
    return elements
  },
  // 案件资源路径
  caseFolder: function (state, getters) {
    return function () {
      if (process.browser) return ''
      let caseFolderPath = remote.getGlobal('CaseFloder')
      caseFolderPath = caseFolderPath ? caseFolderPath + '\\' : ''
      // 创建案件文件夹路径
      if (caseFolderPath && !fs.existsSync(caseFolderPath)) fs.mkdirSync(caseFolderPath)
      return caseFolderPath
    }
  },
  // 编辑器图层
  layers: function (state, getters) {
    return state.elements.filter((x) => {
      return !x.templateElement
    })
      .sort((a, b) => {
        return a.index - b.index
      })
  },
  getFilePath: (state, getters) => (id, type) => {
    let file = state.files.find((item) => {
      return item && item.ID === id
    })
    if (!file) return null
    if (type === 'MEDIA' || type === 'AUDIO') {
      return process.browser ? vue.prototype.getFileUrl(file.IMG) : getters.caseFolder() + file.IMG
    } else {
      return file.IMG
    }
  },
  defaultCover: function (state) {
    let cover = state.covers.find((x) => {
      return state.DefaultCover ? (x.id === state.DefaultCover) : (!x.isCustom)
    })
    return cover || {}
  },
  backgroundImage: function (state) {
    if (!state.slide || !state.styles.length) return null
    let background = state.styles.find((x) => {
      return x.id === state.slide.sid
    })
    return background ? background.image : null
  },
  defaultTemplate: (state) => {
    let template = state.DefaultTemplate.find((x) => {
      return x.sid === state.DefaultBackground
    })
    return template ? template.id : null
  },
  template: (state) => (ID) => {
    return state.templates ? state.templates.filter((x) => {
      return x.sid === ID
    }) : []
  },
  coverTemplate: (state) => {
    let cover = state.styles.find((x) => {
      return x.sffm === 'True'
    })
    return state.DefaultTemplate.find((x) => {
      return x.sid === (cover ? cover.id : null)
    })
  }
}

/**
 * 获取默认幻灯片元素
 * @param {*} obj 元素类型
 * @param {*} customized 用户自定义设置
 */
function getDefaultElement (obj, customized) {
  let defaultEle = JSON.parse(JSON.stringify(defaultElement))
  defaultEle.id = uuid()
  defaultEle.type = obj.ElementType

  // 设置默认进入动画
  let defaultAnimation = customized.DefaultAnimation
  if (defaultAnimation && defaultAnimation.id && defaultAnimation.name && defaultAnimation.time) {
    defaultEle.animation = [{...defaultAnimation}]
  }
  // 设置元素默认字体样式
  if (customized.DefaultElementStyle.name) {
    defaultEle.style['font-family'] = customized.DefaultElementStyle.name
  }
  if (customized.DefaultElementStyle.size) {
    defaultEle.style['font-size'] = customized.DefaultElementStyle.size
  }
  if (customized.DefaultElementStyle.color) {
    defaultEle.style['color'] = customized.DefaultElementStyle.color
  }
  if (customized.DefaultElementStyle.fontWeight) {
    defaultEle.style['font-weight'] = customized.DefaultElementStyle.fontWeight
  }
  switch (obj.ElementType) {
    case 'TEXT':
    case 'IMAGE':
    case 'AUDIO':
    case 'MEDIA':
      break
    case 'STRAGHTLINE':
      defaultEle.style['background-color'] = customized.DefaultGraphStyle.color
      defaultEle.style['border-width'] = customized.DefaultGraphStyle.width
      break
    case 'RECTANGLE':
    case 'ELLIPSE':
      if (customized.DefaultGraphStyle.width) {
        defaultEle.style['border-width'] = customized.DefaultGraphStyle.width
        defaultEle.style['border-style'] = 'solid'
      }
      if (customized.DefaultGraphStyle.color) {
        defaultEle.style['border-color'] = customized.DefaultGraphStyle.color
      }
      break
  }
  return defaultEle
}

/**
 * 获取幻灯片元素集
 * @param {*} style 幻灯片风格
 * @param {*} template 幻灯片模板
 * @param {*} content 参数内容
 * @param {*} defaultEl 默认元素
 */
function getSlideElements (template, content, customized) {
  let elements = []

  let maxIndex = 0
  // //添加幻灯片风格
  // style.sort((a, b) => { return a.index - b.index; }).forEach(item => {
  //     maxIndex++;
  //     item.index = maxIndex;
  //     item.name = item.type + item.index;
  //     elements.push(JSON.parse(JSON.stringify(item)));
  // });

  // 添加幻灯片版式
  template.sort((a, b) => {
    return a.index - b.index
  }).forEach((item) => {
    maxIndex++
    item.index = maxIndex
    item.name = item.type + item.index
    elements.push(JSON.parse(JSON.stringify(item)))
  })
  if (!content || !content.length) return elements

  // 先将模板中元素填充值
  elements.forEach((item) => {
    for (let i = 0; i < content.length; i++) {
      if (item.type === content[i].type && !item.templateElement) {
        item.html = content[i].html
        item.text = content[i].text
        item.path = content[i].path
        item.fileCode = content[i].fileID
        content.splice(i, 1)
        break
      }
    }
  })

  // 在填充多余内容
  content.forEach((item) => {
    // 默认元素
    let defaultEl = getDefaultElement({}, customized)
    let addEl = getElementLocSize(elements, item, defaultEl)
    if (addEl) {
      maxIndex++
      addEl.index = maxIndex
      // 设置元素类型
      addEl.type = item.type
      // 设置元素名称
      addEl.name = addEl.type + addEl.index
      elements.push(addEl)
    }
  })
  return elements
}

function getElementLocSize (elements, content, defaultEl) {
  let addEl = null
  if (content.orientation) {
    // 过滤出模板中相同类型元素并将排序
    let filterEl = elements.filter((x) => {
      return x.type === content.type && !x.templateElement
    }).sort((a, b) => {
      return b.index - a.index
    })

    if (filterEl.length > 0) {
      addEl = JSON.parse(JSON.stringify(filterEl[0]))

      // 重新组织元素位置
      if (content.orientation === 'left') {
        if ((addEl.left + content.distance) >= 0 && addEl.left + addEl.width + content.distance <= 1) {
          addEl.left += content.distance
        }
      } else if (content.orientation === 'top') {
        if ((addEl.top + content.distance) >= 0 && addEl.top + addEl.height + content.distance <= 1) {
          addEl.top += content.distance
        }
      }
    }
  }
  // 当未找到相同类型的模板类型时使用默认的元素对象
  if (!addEl) {
    addEl = JSON.parse(JSON.stringify(defaultEl))
    // 设置默认位置
    addEl.left = content.left ? content.left : addEl.left
    addEl.top = content.top ? content.top : addEl.top
    addEl.width = 1 - addEl.left
    addEl.height = 1 - addEl.top
  } else {
    addEl.id = uuid()
  }

  if (content.size) {
    addEl.width = content.size.width
    if (addEl.left + addEl.width > 1) addEl.left = 1 - addEl.width

    addEl.height = content.size.height
    if (addEl.top + addEl.height > 1) addEl.top = 1 - addEl.height
  }

  if (content.animation && addEl.animation.length) {
    if (!addEl.animation || !addEl.animation.length) {
      addEl.animation = defaultEl.animation
    }
    addEl.animation[0].id = content.animation.id
    addEl.animation[0].name = content.animation.value
  } else {
    addEl.animation = defaultEl.animation
  }

  // 设置文本内容
  addEl.html = content.html
  addEl.text = content.text
  addEl.path = content.path
  addEl.fileCode = content.fileID
  return addEl
}

function getPlaySlide (dataSource, parentNode) {
  let arr = []
  dataSource.forEach((item) => {
    if (Number(item.type) !== 0) {
      arr.push({
        parent: parentNode ? {data: {alias: parentNode.alias}} : null,
        data: item
      })
    }
    if (item.children && item.children.length) {
      arr = arr.concat(getPlaySlide(item.children, item))
    }
  })
  return arr
}

export default {
  state,
  getters,
  mutations,
  actions
}
